# This is a BitKeeper generated patch for the following project: # Project Name: Linux kernel tree # This patch format is intended for GNU patch command version 2.5 or higher. # This patch includes the following deltas: # ChangeSet 1.1069.175.2+1.1069.176.58 -> 1.1069.175.3 # include/acpi/acglobal.h 1.22.1.1 -> 1.24 # drivers/acpi/executer/exoparg3.c 1.8.1.1 -> 1.10 # drivers/acpi/hardware/hwacpi.c 1.15.1.3 -> 1.19 # include/acpi/acutils.h 1.22.1.1 -> 1.24 # drivers/acpi/pci_root.c 1.4.1.2 -> 1.8 # drivers/char/drm-4.0/radeon_drv.c 1.1.1.3 -> 1.6 # drivers/char/drm-4.0/bufs.c 1.1.1.3 -> 1.6 # drivers/acpi/dispatcher/dswload.c 1.18.1.2 -> 1.20.1.1 # drivers/acpi/utilities/uteval.c 1.15.1.1 -> 1.17 # drivers/acpi/events/evrgnini.c 1.16.1.2 -> 1.18 # drivers/acpi/hardware/hwsleep.c 1.22.1.1 -> 1.24 # drivers/acpi/executer/exdump.c 1.15.1.2 -> 1.17 # drivers/char/drm-4.0/tdfx_drv.c 1.2.1.3 -> 1.7 # drivers/acpi/utilities/utglobal.c 1.20.1.4 -> 1.22.1.2 # include/acpi/acobject.h 1.16.1.2 -> 1.18 # drivers/acpi/utilities/utalloc.c 1.14.1.2 -> 1.17 # drivers/acpi/executer/exregion.c 1.14.1.1 -> 1.16 # include/acpi/acpi_drivers.h 1.5.1.2 -> 1.7.1.1 # drivers/char/drm/r128_cce.c 1.5.1.4 -> 1.14 # drivers/char/drm-4.0/i810_drv.c 1.1.1.3 -> 1.6 # drivers/acpi/events/evxfregn.c 1.15.1.2 -> 1.17 # drivers/acpi/parser/psparse.c 1.17.1.2 -> 1.19.1.1 # drivers/acpi/tables.c 1.9.1.3 -> 1.11.1.3 # drivers/char/drm/drm_memory.h 1.3.1.4 -> 1.10 # drivers/char/drm/radeon_cp.c 1.6.1.4 -> 1.14 # drivers/acpi/executer/exprep.c 1.14.1.2 -> 1.17 # drivers/char/Config.in 1.36.1.27 -> 1.39.1.18 # include/acpi/acconfig.h 1.35.1.6 -> 1.37.1.4 # drivers/char/drm/drm_bufs.h 1.5.1.4 -> 1.11 # drivers/acpi/namespace/nsxfname.c 1.14.1.1 -> 1.16 # drivers/acpi/parser/psargs.c 1.16.1.1 -> 1.18 # arch/i386/kernel/mpparse.c 1.27.1.16 -> 1.30.1.10 # drivers/acpi/executer/exfldio.c 1.19.1.3 -> 1.23 # drivers/char/drm/i810_dma.c 1.7.1.5 -> 1.9.1.5 # drivers/char/drm/i830_dma.c 1.2.1.1 -> 1.4 # drivers/acpi/resources/rscreate.c 1.14.1.1 -> 1.16 # drivers/acpi/namespace/nsinit.c 1.18.1.1 -> 1.20 # drivers/acpi/dispatcher/dsmthdat.c 1.18.1.2 -> 1.20 # drivers/acpi/executer/exresolv.c 1.15.1.2 -> 1.18 # drivers/acpi/namespace/nsobject.c 1.14.1.1 -> 1.16 # drivers/char/drm-4.0/r128_drv.c 1.1.1.3 -> 1.6 # drivers/acpi/executer/exstore.c 1.21.1.1 -> 1.23 # drivers/char/drm-4.0/drmP.h 1.1.1.3 -> 1.6 # drivers/acpi/resources/rsirq.c 1.12.1.2 -> 1.15 # drivers/char/drm-4.0/gamma_drv.c 1.1.1.3 -> 1.6 # drivers/acpi/utilities/utdelete.c 1.16.1.2 -> 1.19 # drivers/acpi/dispatcher/dsmethod.c 1.14.1.1 -> 1.16 # drivers/acpi/namespace/nsutils.c 1.21.1.2 -> 1.23.1.1 # drivers/acpi/namespace/nsalloc.c 1.15.1.1 -> 1.17 # drivers/pci/pci.ids 1.44.1.5 -> 1.46.1.2 # drivers/acpi/resources/rscalc.c 1.15.1.1 -> 1.17 # drivers/char/drm-4.0/mga_dma.c 1.1.1.3 -> 1.6 # include/acpi/acmacros.h 1.17.1.1 -> 1.19 # drivers/acpi/bus.c 1.18.1.2 -> 1.21 # drivers/acpi/resources/rsdump.c 1.13.1.1 -> 1.15 # include/acpi/acevents.h 1.16.1.1 -> 1.18 # drivers/acpi/events/evmisc.c 1.20.1.1 -> 1.22 # drivers/acpi/utilities/utdebug.c 1.16.1.1 -> 1.18 # drivers/char/drm-4.0/ffb_drv.c 1.3.1.3 -> 1.8 # drivers/char/drm-4.0/i810_dma.c 1.3.1.5 -> 1.6.1.4 # drivers/char/drm-4.0/r128_cce.c 1.1.1.3 -> 1.8 # drivers/acpi/tables/tbget.c 1.16.1.3 -> 1.18.1.1 # drivers/acpi/utilities/utobject.c 1.16.1.1 -> 1.18 # Makefile 1.190.1.68 -> 1.193.1.41 # drivers/acpi/events/evregion.c 1.17.1.3 -> 1.20 # drivers/acpi/executer/exsystem.c 1.12.1.2 -> 1.15 # drivers/char/drm/drmP.h 1.9.1.4 -> 1.16 # drivers/char/drm-4.0/mga_drv.c 1.1.1.3 -> 1.6 # drivers/acpi/tables/tbxfroot.c 1.14.1.2 -> 1.16.1.1 # drivers/char/drm-4.0/radeon_cp.c 1.1.1.3 -> 1.7 # drivers/acpi/executer/exmutex.c 1.10.1.1 -> 1.12 # drivers/acpi/parser/psxface.c 1.14.1.1 -> 1.16 # drivers/char/drm/drm_drv.h 1.4.1.4 -> 1.10 # drivers/acpi/dispatcher/dsopcode.c 1.17.1.4 -> 1.19.1.2 # drivers/acpi/executer/exmisc.c 1.17.1.1 -> 1.19 # drivers/acpi/hardware/hwregs.c 1.20.1.2 -> 1.22.1.1 # drivers/acpi/Config.in 1.9.1.7 -> 1.12.1.5 # drivers/char/drm/mga_dma.c 1.4.1.5 -> 1.11 # drivers/acpi/executer/exresop.c 1.16.1.2 -> 1.19 # drivers/char/drm-4.0/memory.c 1.1.1.3 -> 1.6 # drivers/acpi/tables/tbxface.c 1.14.1.1 -> 1.16 # drivers/acpi/executer/exoparg1.c 1.17.1.2 -> 1.20 # drivers/acpi/namespace/nsdump.c 1.16.1.2 -> 1.18.1.1 # drivers/char/drm/gamma_dma.c 1.4.1.1 -> 1.6 # Documentation/Configure.help 1.162.1.56 -> 1.166.1.25 # drivers/char/Makefile 1.27.1.14 -> 1.31.1.7 # drivers/acpi/namespace/nsaccess.c 1.18.1.1 -> 1.20 # drivers/acpi/namespace/nssearch.c 1.16.1.2 -> 1.18.1.1 # drivers/acpi/dispatcher/dswexec.c 1.18.1.1 -> 1.20 # drivers/acpi/dispatcher/dswscope.c 1.13.1.2 -> 1.15.1.1 # drivers/char/drm/drm_vm.h 1.12.1.5 -> 1.19 # drivers/acpi/resources/rslist.c 1.11.1.1 -> 1.13 # diff -Nru a/Documentation/Configure.help b/Documentation/Configure.help --- a/Documentation/Configure.help Mon Dec 29 16:08:08 2003 +++ b/Documentation/Configure.help Mon Dec 29 16:08:08 2003 @@ -18502,6 +18502,11 @@ purpose port, say Y here. See . +Support for serial ports defined in ACPI namespace +CONFIG_SERIAL_ACPI + If you wish to enable serial port discovery via the ACPI + namespace, say Y here. If unsure, say N. + Support for PowerMac serial ports CONFIG_MAC_SERIAL If you have Macintosh style serial ports (8 pin mini-DIN), say Y diff -Nru a/Makefile b/Makefile --- a/Makefile Mon Dec 29 16:08:08 2003 +++ b/Makefile Mon Dec 29 16:08:08 2003 @@ -93,6 +93,7 @@ CFLAGS := $(CPPFLAGS) -Wall -Wstrict-prototypes -Wno-trigraphs -O2 \ -fno-strict-aliasing -fno-common +CFLAGS += -g ifndef CONFIG_FRAME_POINTER CFLAGS += -fomit-frame-pointer endif @@ -306,8 +307,7 @@ $(CONFIG_SHELL) scripts/Configure -d arch/$(ARCH)/config.in xconfig: symlinks - $(MAKE) -C scripts kconfig.tk - wish -f scripts/kconfig.tk + @echo -e "***\n* Sorry, xconfig is broken; use \"make menuconfig\" instead.\n***" menuconfig: include/linux/version.h symlinks $(MAKE) -C scripts/lxdialog all diff -Nru a/drivers/acpi/bus.c b/drivers/acpi/bus.c --- a/drivers/acpi/bus.c Mon Dec 29 16:08:08 2003 +++ b/drivers/acpi/bus.c Mon Dec 29 16:08:08 2003 @@ -1407,16 +1407,14 @@ switch (type) { case ACPI_BUS_TYPE_DEVICE: result = acpi_bus_get_status(device); - if (result) - goto end; - break; + if (!result) + break; + if (!device->status.present) + result = -ENOENT; + goto end; default: STRUCT_TO_INT(device->status) = 0x0F; break; - } - if (!device->status.present) { - result = -ENOENT; - goto end; } /* diff -Nru a/drivers/acpi/pci_root.c b/drivers/acpi/pci_root.c --- a/drivers/acpi/pci_root.c Mon Dec 29 16:08:08 2003 +++ b/drivers/acpi/pci_root.c Mon Dec 29 16:08:08 2003 @@ -152,8 +152,6 @@ switch (status) { case AE_OK: root->id.segment = (u16) value; - printk("_SEG exists! Unsupported. Abort.\n"); - BUG(); break; case AE_NOT_FOUND: ACPI_DEBUG_PRINT((ACPI_DB_INFO, @@ -213,7 +211,12 @@ * PCI namespace does not get created until this call is made (and * thus the root bridge's pci_dev does not exist). */ +#ifdef CONFIG_X86 root->bus = pcibios_scan_root(root->id.bus); +#else + root->bus = pcibios_scan_root(root->handle, + root->id.segment, root->id.bus); +#endif if (!root->bus) { ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Bus %02x:%02x not present in PCI namespace\n", diff -Nru a/drivers/acpi/tables.c b/drivers/acpi/tables.c --- a/drivers/acpi/tables.c Mon Dec 29 16:08:08 2003 +++ b/drivers/acpi/tables.c Mon Dec 29 16:08:08 2003 @@ -276,10 +276,17 @@ /* Map the DSDT header via the pointer in the FADT */ if (id == ACPI_DSDT) { - struct acpi_table_fadt *fadt = (struct acpi_table_fadt *) *header; + struct fadt_descriptor_rev2 *fadt = (struct fadt_descriptor_rev2 *) *header; + + if (fadt->revision == 3 && fadt->Xdsdt) { + *header = (void *) __acpi_map_table(fadt->Xdsdt, + sizeof(struct acpi_table_header)); + } else if (fadt->V1_dsdt) { + *header = (void *) __acpi_map_table(fadt->V1_dsdt, + sizeof(struct acpi_table_header)); + } else + *header = 0; - *header = (void *) __acpi_map_table(fadt->dsdt_addr, - sizeof(struct acpi_table_header)); if (!*header) { printk(KERN_WARNING PREFIX "Unable to map DSDT\n"); return -ENODEV; diff -Nru a/drivers/char/Config.in b/drivers/char/Config.in --- a/drivers/char/Config.in Mon Dec 29 16:08:08 2003 +++ b/drivers/char/Config.in Mon Dec 29 16:08:08 2003 @@ -24,6 +24,9 @@ tristate ' Atomwide serial port support' CONFIG_ATOMWIDE_SERIAL tristate ' Dual serial port support' CONFIG_DUALSP_SERIAL fi + if [ "$CONFIG_ACPI" = "y" ]; then + bool ' Support for serial ports defined in ACPI namespace' CONFIG_SERIAL_ACPI + fi fi dep_mbool 'Extended dumb serial driver options' CONFIG_SERIAL_EXTENDED $CONFIG_SERIAL if [ "$CONFIG_SERIAL_EXTENDED" = "y" ]; then diff -Nru a/drivers/char/drm/drm_bufs.h b/drivers/char/drm/drm_bufs.h --- a/drivers/char/drm/drm_bufs.h Mon Dec 29 16:08:08 2003 +++ b/drivers/char/drm/drm_bufs.h Mon Dec 29 16:08:08 2003 @@ -106,7 +106,7 @@ switch ( map->type ) { case _DRM_REGISTERS: case _DRM_FRAME_BUFFER: -#if !defined(__sparc__) && !defined(__alpha__) +#if !defined(__sparc__) && !defined(__alpha__) && !defined(__ia64__) if ( map->offset + map->size < map->offset || map->offset < virt_to_phys(high_memory) ) { DRM(free)( map, sizeof(*map), DRM_MEM_MAPS ); diff -Nru a/drivers/char/drm/drm_memory.h b/drivers/char/drm/drm_memory.h --- a/drivers/char/drm/drm_memory.h Mon Dec 29 16:08:08 2003 +++ b/drivers/char/drm/drm_memory.h Mon Dec 29 16:08:08 2003 @@ -293,6 +293,11 @@ void *DRM(ioremap)(unsigned long offset, unsigned long size, drm_device_t *dev) { void *pt; +#if __REALLY_HAVE_AGP + drm_map_t *map = NULL; + drm_map_list_t *r_list; + struct list_head *list; +#endif if (!size) { DRM_MEM_ERROR(DRM_MEM_MAPPINGS, @@ -300,12 +305,50 @@ return NULL; } +#if __REALLY_HAVE_AGP + if (!dev->agp || dev->agp->cant_use_aperture == 0) + goto standard_ioremap; + + list_for_each(list, &dev->maplist->head) { + r_list = (drm_map_list_t *)list; + map = r_list->map; + if (!map) continue; + if (map->offset <= offset && + (map->offset + map->size) >= (offset + size)) + break; + } + + if (map && map->type == _DRM_AGP) { + struct drm_agp_mem *agpmem; + + for (agpmem = dev->agp->memory; agpmem; agpmem = agpmem->next) { + if (agpmem->bound <= offset && + (agpmem->bound + (agpmem->pages + << PAGE_SHIFT)) >= (offset + size)) + break; + } + + if (agpmem == NULL) + goto ioremap_failure; + + pt = agpmem->memory->vmptr + (offset - agpmem->bound); + goto ioremap_success; + } + +standard_ioremap: +#endif if (!(pt = ioremap(offset, size))) { +#if __REALLY_HAVE_AGP +ioremap_failure: +#endif spin_lock(&DRM(mem_lock)); ++DRM(mem_stats)[DRM_MEM_MAPPINGS].fail_count; spin_unlock(&DRM(mem_lock)); return NULL; } +#if __REALLY_HAVE_AGP +ioremap_success: +#endif spin_lock(&DRM(mem_lock)); ++DRM(mem_stats)[DRM_MEM_MAPPINGS].succeed_count; DRM(mem_stats)[DRM_MEM_MAPPINGS].bytes_allocated += size; @@ -316,6 +359,11 @@ void *DRM(ioremap_nocache)(unsigned long offset, unsigned long size, drm_device_t *dev) { void *pt; +#if __REALLY_HAVE_AGP + drm_map_t *map = NULL; + drm_map_list_t *r_list; + struct list_head *list; +#endif if (!size) { DRM_MEM_ERROR(DRM_MEM_MAPPINGS, @@ -323,12 +371,50 @@ return NULL; } +#if __REALLY_HAVE_AGP + if (!dev->agp || dev->agp->cant_use_aperture == 0) + goto standard_ioremap; + + list_for_each(list, &dev->maplist->head) { + r_list = (drm_map_list_t *)list; + map = r_list->map; + if (!map) continue; + if (map->offset <= offset && + (map->offset + map->size) >= (offset + size)) + break; + } + + if (map && map->type == _DRM_AGP) { + struct drm_agp_mem *agpmem; + + for (agpmem = dev->agp->memory; agpmem; agpmem = agpmem->next) { + if (agpmem->bound <= offset && + (agpmem->bound + (agpmem->pages + << PAGE_SHIFT)) >= (offset + size)) + break; + } + + if (agpmem == NULL) + goto ioremap_failure; + + pt = agpmem->memory->vmptr + (offset - agpmem->bound); + goto ioremap_success; + } + +standard_ioremap: +#endif if (!(pt = ioremap_nocache(offset, size))) { +#if __REALLY_HAVE_AGP +ioremap_failure: +#endif spin_lock(&DRM(mem_lock)); ++DRM(mem_stats)[DRM_MEM_MAPPINGS].fail_count; spin_unlock(&DRM(mem_lock)); return NULL; } +#if __REALLY_HAVE_AGP +ioremap_success: +#endif spin_lock(&DRM(mem_lock)); ++DRM(mem_stats)[DRM_MEM_MAPPINGS].succeed_count; DRM(mem_stats)[DRM_MEM_MAPPINGS].bytes_allocated += size; @@ -344,7 +430,11 @@ if (!pt) DRM_MEM_ERROR(DRM_MEM_MAPPINGS, "Attempt to free NULL pointer\n"); +#if __REALLY_HAVE_AGP + else if (!dev->agp || dev->agp->cant_use_aperture == 0) +#else else +#endif iounmap(pt); spin_lock(&DRM(mem_lock)); diff -Nru a/drivers/char/drm/drm_vm.h b/drivers/char/drm/drm_vm.h --- a/drivers/char/drm/drm_vm.h Mon Dec 29 16:08:08 2003 +++ b/drivers/char/drm/drm_vm.h Mon Dec 29 16:08:08 2003 @@ -368,6 +368,7 @@ drm_map_list_t *r_list; unsigned long offset = 0; struct list_head *list; + struct page *page; DRM_DEBUG("start = 0x%lx, end = 0x%lx, offset = 0x%lx\n", vma->vm_start, vma->vm_end, VM_OFFSET(vma)); @@ -414,28 +415,30 @@ switch (map->type) { case _DRM_AGP: -#if defined(__alpha__) - /* - * On Alpha we can't talk to bus dma address from the - * CPU, so for memory of type DRM_AGP, we'll deal with - * sorting out the real physical pages and mappings - * in nopage() - */ - vma->vm_ops = &DRM(vm_ops); - break; +#if __REALLY_HAVE_AGP + if (dev->agp->cant_use_aperture) { + /* + * On some systems we can't talk to bus dma address from + * the CPU, so for memory of type DRM_AGP, we'll deal + * with sorting out the real physical pages and mappings + * in nopage() + */ + vma->vm_ops = &DRM(vm_ops); + goto mapswitch_out; + } #endif /* fall through to _DRM_FRAME_BUFFER... */ case _DRM_FRAME_BUFFER: case _DRM_REGISTERS: - if (VM_OFFSET(vma) >= __pa(high_memory)) { + page = virt_to_page(__va(VM_OFFSET(vma))); + if (!VALID_PAGE(page) || PageReserved(page)) { #if defined(__i386__) || defined(__x86_64__) if (boot_cpu_data.x86 > 3 && map->type != _DRM_AGP) { pgprot_val(vma->vm_page_prot) |= _PAGE_PCD; pgprot_val(vma->vm_page_prot) &= ~_PAGE_PWT; } #elif defined(__ia64__) - if (map->type != _DRM_AGP) - vma->vm_page_prot = + vma->vm_page_prot = pgprot_writecombine(vma->vm_page_prot); #elif defined(__powerpc__) pgprot_val(vma->vm_page_prot) |= _PAGE_NO_CACHE | _PAGE_GUARDED; @@ -474,6 +477,9 @@ default: return -EINVAL; /* This should never happen. */ } +#if __REALLY_HAVE_AGP +mapswitch_out: +#endif vma->vm_flags |= VM_RESERVED; /* Don't swap */ vma->vm_file = filp; /* Needed for drm_vm_open() */ diff -Nru a/drivers/char/drm/r128_cce.c b/drivers/char/drm/r128_cce.c --- a/drivers/char/drm/r128_cce.c Mon Dec 29 16:08:08 2003 +++ b/drivers/char/drm/r128_cce.c Mon Dec 29 16:08:08 2003 @@ -216,7 +216,22 @@ int i; for ( i = 0 ; i < dev_priv->usec_timeout ; i++ ) { +#ifndef CONFIG_AGP_I460 if ( GET_RING_HEAD( &dev_priv->ring ) == dev_priv->ring.tail ) { +#else + /* + * XXX - this is (I think) a 460GX specific hack + * + * When doing texturing, ring.tail sometimes gets ahead of + * PM4_BUFFER_DL_WPTR by 2; consequently, the card processes + * its whole quota of instructions and *ring.head is still 2 + * short of ring.tail. Work around this for now in lieu of + * a better solution. + */ + if ( GET_RING_HEAD( &dev_priv->ring ) == dev_priv->ring.tail || + ( dev_priv->ring.tail - + GET_RING_HEAD( &dev_priv->ring ) ) == 2 ) { +#endif int pm4stat = R128_READ( R128_PM4_STAT ); if ( ( (pm4stat & R128_PM4_FIFOCNT_MASK) >= dev_priv->cce_fifo_size ) && @@ -317,7 +332,7 @@ static void r128_cce_init_ring_buffer( drm_device_t *dev, drm_r128_private_t *dev_priv ) { - u32 ring_start; + u32 ring_start, rptr_addr; u32 tmp; DRM_DEBUG( "\n" ); @@ -341,8 +356,24 @@ SET_RING_HEAD( &dev_priv->ring, 0 ); if ( !dev_priv->is_pci ) { - R128_WRITE( R128_PM4_BUFFER_DL_RPTR_ADDR, - dev_priv->ring_rptr->offset ); + /* + * 460GX doesn't claim PCI writes from the card into + * the AGP aperture, so we have to get space outside + * the aperture for RPTR_ADDR. + */ + if ( dev->agp->agp_info.chipset == INTEL_460GX ) { + unsigned long alt_rh_off; + + alt_rh_off = __get_free_page(GFP_KERNEL | GFP_DMA); + atomic_inc(&virt_to_page(alt_rh_off)->count); + set_bit(PG_locked, &virt_to_page(alt_rh_off)->flags); + + dev_priv->ring.head = (__volatile__ u32 *) alt_rh_off; + SET_RING_HEAD( &dev_priv->ring, 0 ); + rptr_addr = __pa( dev_priv->ring.head ); + } else + rptr_addr = dev_priv->ring_rptr->offset; + R128_WRITE( R128_PM4_BUFFER_DL_RPTR_ADDR, rptr_addr ); } else { drm_sg_mem_t *entry = dev->sg; unsigned long tmp_ofs, page_ofs; @@ -629,7 +660,19 @@ DRM_ERROR( "failed to cleanup PCI GART!\n" ); } #endif - + /* + * Free the page we grabbed for RPTR_ADDR + */ + if ( !dev_priv->is_pci && dev->agp->agp_info.chipset == INTEL_460GX ) { + unsigned long alt_rh_off = + (unsigned long) dev_priv->ring.head; + struct page *p = virt_to_page((void *)alt_rh_off); + + put_page(p); + unlock_page(p); + free_page(alt_rh_off); + } + DRM(free)( dev->dev_private, sizeof(drm_r128_private_t), DRM_MEM_DRIVER ); dev->dev_private = NULL; diff -Nru a/drivers/char/drm/radeon_cp.c b/drivers/char/drm/radeon_cp.c --- a/drivers/char/drm/radeon_cp.c Mon Dec 29 16:08:08 2003 +++ b/drivers/char/drm/radeon_cp.c Mon Dec 29 16:08:08 2003 @@ -854,7 +854,7 @@ static void radeon_cp_init_ring_buffer( drm_device_t *dev, drm_radeon_private_t *dev_priv ) { - u32 ring_start, cur_read_ptr; + u32 ring_start, cur_read_ptr, rptr_addr; u32 tmp; /* Initialize the memory controller */ @@ -892,8 +892,24 @@ dev_priv->ring.tail = cur_read_ptr; if ( !dev_priv->is_pci ) { - RADEON_WRITE( RADEON_CP_RB_RPTR_ADDR, - dev_priv->ring_rptr->offset ); + /* + * 460GX doesn't claim PCI writes from the card into + * the AGP aperture, so we have to get space outside + * the aperture for RPTR_ADDR. + */ + if ( dev->agp->agp_info.chipset == INTEL_460GX ) { + unsigned long alt_rh_off; + + alt_rh_off = __get_free_page(GFP_KERNEL | GFP_DMA); + atomic_inc(&virt_to_page(alt_rh_off)->count); + set_bit(PG_locked, &virt_to_page(alt_rh_off)->flags); + + dev_priv->ring.head = (__volatile__ u32 *) alt_rh_off; + *dev_priv->ring.head = cur_read_ptr; + rptr_addr = __pa( dev_priv->ring.head ); + } else + rptr_addr = dev_priv->ring_rptr->offset; + RADEON_WRITE( RADEON_CP_RB_RPTR_ADDR, rptr_addr ); } else { drm_sg_mem_t *entry = dev->sg; unsigned long tmp_ofs, page_ofs; @@ -1278,6 +1294,19 @@ #endif /* __REALLY_HAVE_SG */ } + /* + * Free the page we grabbed for RPTR_ADDR + */ + if ( !dev_priv->is_pci && dev->agp->agp_info.chipset == INTEL_460GX ) { + unsigned long alt_rh_off = + (unsigned long) dev_priv->ring.head; + struct page *p = virt_to_page((void *)alt_rh_off); + + put_page(p); + unlock_page(p); + free_page(alt_rh_off); + } + DRM(free)( dev->dev_private, sizeof(drm_radeon_private_t), DRM_MEM_DRIVER ); dev->dev_private = NULL; diff -Nru a/drivers/char/drm-4.0/bufs.c b/drivers/char/drm-4.0/bufs.c --- a/drivers/char/drm-4.0/bufs.c Mon Dec 29 16:08:08 2003 +++ b/drivers/char/drm-4.0/bufs.c Mon Dec 29 16:08:08 2003 @@ -73,7 +73,7 @@ switch (map->type) { case _DRM_REGISTERS: case _DRM_FRAME_BUFFER: -#ifndef __sparc__ +#if !defined(__sparc__) && !defined(__ia64__) if (map->offset + map->size < map->offset || map->offset < virt_to_phys(high_memory)) { drm_free(map, sizeof(*map), DRM_MEM_MAPS); diff -Nru a/drivers/char/drm-4.0/drmP.h b/drivers/char/drm-4.0/drmP.h --- a/drivers/char/drm-4.0/drmP.h Mon Dec 29 16:08:08 2003 +++ b/drivers/char/drm-4.0/drmP.h Mon Dec 29 16:08:08 2003 @@ -510,6 +510,8 @@ int acquired; unsigned long base; int agp_mtrr; + int cant_use_aperture; + unsigned long page_mask; } drm_agp_head_t; #endif diff -Nru a/drivers/char/drm-4.0/memory.c b/drivers/char/drm-4.0/memory.c --- a/drivers/char/drm-4.0/memory.c Mon Dec 29 16:08:08 2003 +++ b/drivers/char/drm-4.0/memory.c Mon Dec 29 16:08:08 2003 @@ -306,12 +306,44 @@ return NULL; } + if (dev->agp->cant_use_aperture) { + drm_map_t *map = NULL; + int i; + + for (i = 0; i < dev->map_count; i++) { + map = dev->maplist[i]; + if (!map) continue; + if (map->offset <= offset && + (map->offset + map->size) >= (offset + size)) + break; + } + + if (map && map->type == _DRM_AGP) { + struct drm_agp_mem *agpmem; + + for (agpmem = dev->agp->memory; agpmem; + agpmem = agpmem->next) { + if(agpmem->bound <= offset && + (agpmem->bound + (agpmem->pages + << PAGE_SHIFT)) >= (offset + size)) + break; + } + + if (agpmem) { + pt = agpmem->memory->vmptr + (offset - agpmem->bound); + goto ioremap_success; + } + } + } + if (!(pt = ioremap(offset, size))) { spin_lock(&drm_mem_lock); ++drm_mem_stats[DRM_MEM_MAPPINGS].fail_count; spin_unlock(&drm_mem_lock); return NULL; } + +ioremap_success: spin_lock(&drm_mem_lock); ++drm_mem_stats[DRM_MEM_MAPPINGS].succeed_count; drm_mem_stats[DRM_MEM_MAPPINGS].bytes_allocated += size; @@ -327,7 +359,7 @@ if (!pt) DRM_MEM_ERROR(DRM_MEM_MAPPINGS, "Attempt to free NULL pointer\n"); - else + else if (dev->agp->cant_use_aperture == 0) iounmap(pt); spin_lock(&drm_mem_lock); diff -Nru a/drivers/char/drm-4.0/mga_dma.c b/drivers/char/drm-4.0/mga_dma.c --- a/drivers/char/drm-4.0/mga_dma.c Mon Dec 29 16:08:08 2003 +++ b/drivers/char/drm-4.0/mga_dma.c Mon Dec 29 16:08:08 2003 @@ -741,10 +741,18 @@ return -ENOMEM; } - /* Write status page when secend or softrap occurs */ + /* Write status page when secend or softrap occurs + * + * Disable this on ia64 on the off chance that real status page will be + * above 4GB. + */ +#if defined(__ia64__) + MGA_WRITE(MGAREG_PRIMPTR, + virt_to_bus((void *)dev_priv->real_status_page)); +#else MGA_WRITE(MGAREG_PRIMPTR, virt_to_bus((void *)dev_priv->real_status_page) | 0x00000003); - +#endif /* Private is now filled in, initialize the hardware */ { diff -Nru a/drivers/char/drm-4.0/r128_cce.c b/drivers/char/drm-4.0/r128_cce.c --- a/drivers/char/drm-4.0/r128_cce.c Mon Dec 29 16:08:08 2003 +++ b/drivers/char/drm-4.0/r128_cce.c Mon Dec 29 16:08:08 2003 @@ -229,7 +229,21 @@ int i; for ( i = 0 ; i < dev_priv->usec_timeout ; i++ ) { +#ifndef CONFIG_AGP_I460 if ( *dev_priv->ring.head == dev_priv->ring.tail ) { +#else + /* + * XXX - this is (I think) a 460GX specific hack + * + * When doing texturing, ring.tail sometimes gets ahead of + * PM4_BUFFER_DL_WPTR by 2; consequently, the card processes + * its whole quota of instructions and *ring.head is still 2 + * short of ring.tail. Work around this for now in lieu of + * a better solution. + */ + if ( (*dev_priv->ring.head == dev_priv->ring.tail) || + ((dev_priv->ring.tail - *dev_priv->ring.head) == 2) ) { +#endif int pm4stat = R128_READ( R128_PM4_STAT ); if ( ( (pm4stat & R128_PM4_FIFOCNT_MASK) >= dev_priv->cce_fifo_size ) && @@ -330,7 +344,7 @@ static void r128_cce_init_ring_buffer( drm_device_t *dev ) { drm_r128_private_t *dev_priv = dev->dev_private; - u32 ring_start; + u32 ring_start, rptr_addr; u32 tmp; /* The manual (p. 2) says this address is in "VM space". This @@ -342,10 +356,27 @@ R128_WRITE( R128_PM4_BUFFER_DL_WPTR, 0 ); R128_WRITE( R128_PM4_BUFFER_DL_RPTR, 0 ); + /* + * 460GX doesn't claim PCI writes from the card into the AGP + * aperture, so we have to get space outside the aperture for + * RPTR_ADDR. + */ + if ( dev->agp->agp_info.chipset == INTEL_460GX ) { + unsigned long alt_rh_off; + + alt_rh_off = __get_free_page(GFP_KERNEL | GFP_DMA); + atomic_inc(&virt_to_page(alt_rh_off)->count); + set_bit(PG_locked, &virt_to_page(alt_rh_off)->flags); + + dev_priv->ring.head = (__volatile__ u32 *) alt_rh_off; + rptr_addr = __pa( dev_priv->ring.head ); + } else { + rptr_addr = dev_priv->ring_rptr->offset; + } + /* DL_RPTR_ADDR is a physical address in AGP space. */ *dev_priv->ring.head = 0; - R128_WRITE( R128_PM4_BUFFER_DL_RPTR_ADDR, - dev_priv->ring_rptr->offset ); + R128_WRITE( R128_PM4_BUFFER_DL_RPTR_ADDR, rptr_addr ); /* Set watermark control */ R128_WRITE( R128_PM4_BUFFER_WM_CNTL, @@ -529,6 +560,19 @@ DO_REMAPFREE( dev_priv->agp_textures, dev ); } #endif + + /* + * Free the page we grabbed for RPTR_ADDR + */ + if ( dev->agp->agp_info.chipset == INTEL_460GX ) { + unsigned long alt_rh_off = + (unsigned long) dev_priv->ring.head; + + atomic_dec(&virt_to_page(alt_rh_off)->count); + clear_bit(PG_locked, &virt_to_page(alt_rh_off)->flags); + wake_up(&virt_to_page(alt_rh_off)->wait); + free_page(alt_rh_off); + } drm_free( dev->dev_private, sizeof(drm_r128_private_t), DRM_MEM_DRIVER ); diff -Nru a/drivers/char/drm-4.0/radeon_cp.c b/drivers/char/drm-4.0/radeon_cp.c --- a/drivers/char/drm-4.0/radeon_cp.c Mon Dec 29 16:08:08 2003 +++ b/drivers/char/drm-4.0/radeon_cp.c Mon Dec 29 16:08:08 2003 @@ -569,7 +569,7 @@ static void radeon_cp_init_ring_buffer( drm_device_t *dev ) { drm_radeon_private_t *dev_priv = dev->dev_private; - u32 ring_start, cur_read_ptr; + u32 ring_start, cur_read_ptr, rptr_addr; u32 tmp; /* Initialize the memory controller */ @@ -592,10 +592,29 @@ /* Initialize the ring buffer's read and write pointers */ cur_read_ptr = RADEON_READ( RADEON_CP_RB_RPTR ); RADEON_WRITE( RADEON_CP_RB_WPTR, cur_read_ptr ); + *dev_priv->ring.head = cur_read_ptr; dev_priv->ring.tail = cur_read_ptr; - RADEON_WRITE( RADEON_CP_RB_RPTR_ADDR, dev_priv->ring_rptr->offset ); + /* + * 460GX doesn't claim PCI writes from the card into the AGP + * aperture, so we have to get space outside the aperture for + * RPTR_ADDR. + */ + if ( dev->agp->agp_info.chipset == INTEL_460GX ) { + unsigned long alt_rh_off; + + alt_rh_off = __get_free_page(GFP_KERNEL | GFP_DMA); + atomic_inc(&virt_to_page(alt_rh_off)->count); + set_bit(PG_locked, &virt_to_page(alt_rh_off)->flags); + + dev_priv->ring.head = (__volatile__ u32 *) alt_rh_off; + *dev_priv->ring.head = cur_read_ptr; + rptr_addr = __pa( dev_priv->ring.head ); + } else + rptr_addr = dev_priv->ring_rptr->offset; + + RADEON_WRITE( RADEON_CP_RB_RPTR_ADDR, rptr_addr); /* Set ring buffer size */ RADEON_WRITE( RADEON_CP_RB_CNTL, dev_priv->ring.size_l2qw ); @@ -836,6 +855,19 @@ DO_IOREMAPFREE( dev_priv->agp_textures, dev ); } #endif + + /* + * Free the page we grabbed for RPTR_ADDR. + */ + if ( dev->agp->agp_info.chipset == INTEL_460GX ) { + unsigned long alt_rh_off = + (unsigned long) dev_priv->ring.head; + + atomic_dec(&virt_to_page(alt_rh_off)->count); + clear_bit(PG_locked, &virt_to_page(alt_rh_off)->flags); + wake_up(&virt_to_page(alt_rh_off)->wait); + free_page(alt_rh_off); + } drm_free( dev->dev_private, sizeof(drm_radeon_private_t), DRM_MEM_DRIVER );